package sk.naive.talker;

import sk.naive.talker.props.PropertyStoreException;

import java.rmi.RemoteException;

/**
 * IdleCalculator.
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.3 $ $Date: 2005/02/12 10:08:59 $
 */
public class UserTimeStatisticsCalculator {
	private User user;
	private long timestamp;
	private long lastAction;
	private long lastTltSave;
	private long loginTime;
	private long totalLoginTime;
	private long totalAfkTime;
	private long totalIdleTime;
	private AfkStatus afkStatus;

	public UserTimeStatisticsCalculator(User user) throws PropertyStoreException {
		this.user = user;
		timestamp = System.currentTimeMillis();
		totalLoginTime = (Long) user.get(User.UPROP_TOTAL_LOGIN_TIME);
		totalAfkTime = (Long) user.get(User.UPROP_TOTAL_AFK_TIME);
		totalIdleTime = (Long) user.get(User.UPROP_TOTAL_IDLE_TIME);
		if (user.isOnline()) {
			lastAction = (Long) user.get(User.UPROP_LAST_ACTION_TIME);
			lastTltSave = (Long) user.get(User.UPROP_LAST_TLT_SAVE);
			loginTime = (Long) user.get(User.UPROP_LOGIN_TIME);
			afkStatus = new AfkHelper(user).getStatus();
			if (afkStatus != null) {
				// TODO co osetruje toto? (asi zaciatok ratania pripadneho idle :-))
				lastAction = afkStatus.getAfkStart();
				totalAfkTime += timestamp - afkStatus.getAfkStart();
			}
			totalLoginTime += timestamp - lastTltSave;
		}
	}

	public boolean isAfk() {
		return (afkStatus != null);
	}

	public String afkReason() {
		return afkStatus.getReason();
	}

	public long idleTime() {
		return (timestamp - lastAction);
	}

	public long sessionTime() {
		return (timestamp - loginTime);
	}

	public User getUser() {
		return user;
	}

	public long getTotalLoginTime() {
		return totalLoginTime;
	}

	public long getTotalAfkTime() {
		return totalAfkTime;
	}

	public long getTotalIdleTime() {
		return totalIdleTime;
	}

	public void updateLastAction() throws PropertyStoreException {
		user.set(User.UPROP_LAST_ACTION_TIME, timestamp);
	}

	public void resetAfkIdle(Talker talker, String action) throws RemoteException, PropertyStoreException {
		if (afkStatus != null) {
			new AfkHelper(user).unset(talker, action != null);
			if (action != null) {
				updateLastAction();
				updateTotalLogin();
			}
		} else {
			long idleTime = timestamp - lastAction;
			if (idleTresholdReached(talker, idleTime)) {
				idleTime -= ((Integer) talker.get(Consts.TPROP_IDLE_BASE)) * Consts.MINUTE_MILLIS;
				if (idleTime < 0) {
					idleTime = 0;
				}
				user.set(User.UPROP_TOTAL_IDLE_TIME, idleTime + (Long) user.get(User.UPROP_TOTAL_IDLE_TIME));
				if (action != null) {
					updateLastAction();
				}
				updateTotalLogin();
			}
		}
	}

	private boolean idleTresholdReached(Talker talker, long idleTime) throws PropertyStoreException {
		return idleTime >= (((Integer) talker.get(Consts.TPROP_IDLE_TRESHOLD)) * Consts.MINUTE_MILLIS);
	}

	public void updateLogoutInformation() throws PropertyStoreException {
		user.set(User.UPROP_LAST_LOGIN, timestamp);
		user.set(User.UPROP_LAST_SESSION_TIME, timestamp - loginTime);
		updateTotalLogin();
	}

	private void updateTotalLogin() throws PropertyStoreException {
		user.set(User.UPROP_LAST_TLT_SAVE, timestamp);
		user.set(User.UPROP_TOTAL_LOGIN_TIME, totalLoginTime);
	}
}
